home *** CD-ROM | disk | FTP | other *** search
/ Revolution - Das Atari CD Magazin 1997 / Revolution - Das Atari CD Magazin 1.iso / software / anwendng / utility / cbhd502 / src / c / srchdrv.c < prev   
C/C++ Source or Header  |  1997-01-21  |  13KB  |  527 lines

  1. /*{{{}}}*/
  2. /****************************************************************************
  3.  *
  4.  * Beispiel für die Benutzung des SCSI-Treibers
  5.  * Suche nach vorhandenen Geräten.
  6.  *
  7.  * $Source: u:\k\usr\src\scsi\cbhd\rcs\srchdrv.c,v $
  8.  *
  9.  * $Revision: 1.6 $
  10.  *
  11.  * $Author: Steffen_Engel $
  12.  *
  13.  * $Date: 1996/02/14 11:29:58 $
  14.  *
  15.  * $State: Exp $
  16.  *
  17.  *****************************************************************************
  18.  * History:
  19.  *
  20.  * $Log: srchdrv.c,v $
  21.  * Revision 1.6  1996/02/14  11:29:58  Steffen_Engel
  22.  * Diverser Kleinkram
  23.  *
  24.  * Revision 1.5  1995/11/28  19:14:14  S_Engel
  25.  * *** empty log message ***
  26.  *
  27.  * Revision 1.4  1995/11/14  22:15:26  S_Engel
  28.  * Meldung von CanDisconnect und ScatterGather
  29.  *
  30.  * Revision 1.3  1995/10/22  15:42:28  S_Engel
  31.  * Anpassung auf lange Handles
  32.  *
  33.  * Revision 1.2  1995/09/29  09:18:56  S_Engel
  34.  * Jetzt ist es Warning Free :-)
  35.  *
  36.  * Revision 1.1  1995/06/16  12:06:46  S_Engel
  37.  * Initial revision
  38.  *
  39.  *
  40.  *
  41.  ****************************************************************************/
  42.  
  43. #include <stdio.h>
  44.  
  45. #include <import.h>
  46. #include <portab.h>
  47.  
  48. #include <scsidrv/scsiio.h>
  49. #include <scsidrv/scsi.h>
  50. #include <scsidrv/scsidisk.h>
  51. #include <export.h>
  52.  
  53. #define DUMPBLOCKS  0     /* zur Demo der Datentransfers, gleichzeitig Anzahl */
  54. #define READONLY    0     /* Blöcke nur Testlesen, nicht zeigen */
  55.  
  56. #define MIN(A,B) A>B ? B:A
  57.  
  58. typedef struct head
  59. {
  60.   int valid     : 1; 
  61.   int ErrorCode : 7;
  62. } HEADBITS;
  63.  
  64. typedef struct key
  65. {
  66.   int FM       : 1;
  67.   int EOM      : 1;
  68.   int ILI      : 1;
  69.   int reserved : 1;
  70.   Key          : 4;
  71. } KEY;
  72.  
  73. typedef struct reqsense
  74. {
  75.   char HeadBits;    /* eigentlich HEADBITS, aber Bitfield mindestens 16 Bit */
  76.   char SegmentNo;
  77.   char SenseKey;    /* eigentlich KEY, aber... */
  78.   char InfoByte1;
  79.   char InfoByte2;
  80.   char InfoByte3;
  81.   char InfoByte4;
  82.   char AddLength;
  83.   unsigned long  CmdSpecific;
  84.   char AS;
  85.   char ASQ;
  86. } REQSENSE;
  87.  
  88.  
  89. typedef struct tcall
  90. {
  91.   int   num;
  92.   long  Call;
  93. } TCALL;
  94.  
  95.  
  96. char NoSense[]          = "Kein Fehler?";
  97. char ReqSenseError[]    = "Fehler bei Request Sense!";
  98. char UnknownError[]     = "Unbekannter Fehler";
  99. char FileMark[]         = "Filemark";
  100. char EndOfMedia[]       = "Bandende";
  101. char IllegalLength[]    = "IllegalLength";
  102. char RecoveredError[]   = "Korrigierter Lesefehler";
  103. char NotReady[]         = "Nicht bereit";
  104. char MediumError[]      = "Medium-Fehler";
  105. char HardwareError[]    = "Hardware-Fehler";
  106. char IllegalRequest[]   = "Illegaler Befehl";
  107. char UnitAttention[]    = "Unit Attention";
  108. char DataProtect[]      = "Schreibschutz";
  109. char BlankCheck[]       = "Keine Daten auf dem Band";
  110. char CopyAborted[]      = "Abbruch von 'Copy'";
  111. char AbortedCommand[]   = "Abgebrocheneds Kommando";
  112. char Equal[]            = "Equal";
  113. char VolumeOverflow[]   = "Volume Overflow/Bandende";
  114. char Miscompare[]       = "Miscompare";
  115.  
  116.  
  117.  
  118.  
  119. /***********************************************
  120.  * Text für AS und ASQ aus REQSENSE.DAT lesen  *
  121.  ***********************************************/
  122. void GetAS(char buffer[], int AS, int ASQ)
  123. {{{
  124.   
  125.   char fname[512], msg[120];
  126.   int count, as, asq; 
  127.   FILE *file;
  128.  
  129.   strcpy(fname, "reqsense.dat");
  130.   file = fopen(fname, "r");
  131.  
  132.   if (file == NULL)
  133.     {
  134.       strcpy(buffer, "REQSENSE.PLG: ");
  135.       strcat(buffer, fname);
  136.       strcat(buffer, " not found");
  137.       /* Ende der Datei -> AS und ASQ an bereits existierende Meldung anhängen */
  138.       sprintf(msg, ": AS: $%02x, ASQ: $%02x", AS, ASQ);
  139.       strcat (buffer, msg);
  140.       return;
  141.     }
  142.  
  143.   while (1)
  144.   {
  145.     if (fscanf(file, "%x %x %[#-z ]", &as, &asq, msg) == 0) 
  146.       {
  147.         /* Ende der Datei -> AS und ASQ an bereits existierende Meldung anhängen */
  148.         sprintf(msg, ": AS: $%02x, ASQ: $%02x", AS, ASQ);
  149.         strcat (buffer, msg);
  150.         break;
  151.       }
  152.     if ((AS == as) && ((ASQ == asq) || (asq == 0xFF)))
  153.     {
  154.       strcpy(buffer, msg);
  155.  
  156.       /* qualifier mit FF soll in Text einkopiert werden */
  157.       if (asq == 0xFF)
  158.         {
  159.           sprintf(buffer, msg, ASQ);
  160.         }
  161.       break;        
  162.     }
  163.   }
  164.   fclose(file);   /* Datei schließen */
  165. }}}   /* GetAS */
  166.  
  167.  
  168. /***********************************************
  169.  * die eigentliche Plug-Prozedur               *
  170.  ***********************************************/
  171. BOOLEAN SenseMsg(REQSENSE *SenseData, char *Msg)
  172. {{{
  173.   if ((long) SenseData != -1)      /* beim Deinit-Call nichts machen */
  174.     {
  175.       if ((((int) SenseData->HeadBits & 0x7f) != 0x70)
  176.            && (((int) SenseData->HeadBits & 0x7f) != 0x71))
  177.       {
  178.         strcpy (Msg, "Was'n das'n?");
  179.       }
  180.       else
  181.       {
  182.         switch (SenseData->SenseKey & 0x0F)
  183.         {
  184. /* Es kann sein, daß der SenseKey 0 ist, aber in den beren Bits etwas markiert ist.
  185.           case 0x00: strcpy(Msg, NoSense); 
  186.                      break;
  187.  */ 
  188.           case 0x01: strcpy(Msg, RecoveredError);
  189.                      break;
  190.           case 0x02: strcpy(Msg, NotReady);
  191.                      break;
  192.           case 0x03: strcpy(Msg, MediumError);
  193.                      break;
  194.           case 0x04: strcpy(Msg, HardwareError);
  195.                      break;
  196.           case 0x05: strcpy(Msg, IllegalRequest);
  197.                      break;
  198.           case 0x06: strcpy(Msg, UnitAttention);
  199.                      break;
  200.           case 0x07: strcpy(Msg, DataProtect);
  201.                      break;
  202.           case 0x08: strcpy(Msg, BlankCheck);
  203.                      break;
  204.       /* |09H : RETURN VendorUnique; */
  205.           case 0x0A: strcpy(Msg, CopyAborted);
  206.                      break;
  207.           case 0x0B: strcpy(Msg, AbortedCommand);
  208.                      break;
  209.           case 0x0C: strcpy(Msg, Equal);
  210.                      break;
  211.           case 0x0D: strcpy(Msg, VolumeOverflow);
  212.                      break;
  213.           case 0x0E: strcpy(Msg, Miscompare);
  214.                      break;
  215.           
  216.           default:   if (SenseData->SenseKey & 0x80)
  217.                      {
  218.                        strcpy(Msg, FileMark);
  219.                      } 
  220.                      else
  221.                      {
  222.                        if (SenseData->SenseKey & 0x40)
  223.                        {
  224.                          strcpy(Msg, EndOfMedia);
  225.                        }
  226.                        else
  227.                        {
  228.                          if (SenseData->SenseKey & 0x20)
  229.                          {
  230.                            strcpy(Msg, IllegalLength);
  231.                          }
  232.                          else
  233.                          {
  234.                            sprintf(Msg, " Code : $%x Key : $%x", 
  235.                                    SenseData->HeadBits, SenseData->SenseKey);
  236.                          }
  237.                        }
  238.                      }
  239.         }
  240.       }
  241.       
  242.       /* und den Additional Sense-Code, wenn er gemeldet ist */
  243.       if (SenseData->AS != 0)
  244.       {
  245.         GetAS(Msg, SenseData->AS, SenseData->ASQ);
  246.       }
  247.        return TRUE;
  248.     }
  249.   else
  250.     {
  251.       return FALSE;
  252.     }
  253. }}}     /* CallProc */
  254.  
  255.  
  256.  
  257. /***********************************************
  258.  * Daten dumpen
  259.  *
  260.  * noch nicht ausgearbeitet, beherrscht nur vielfache von 16 Bytes!
  261.  *
  262.  ***********************************************/
  263. void dump(unsigned char *data, ULONG len)
  264. {{{
  265. WORD count1, count2;
  266.  
  267.   /* Schleife über 16 Bytes */
  268.   for (count1 = 0; count1 < len/16; count1++)
  269.   {
  270.     printf("      $%04x ", count1*16);
  271.     for (count2 = 0; count2 < 16; count2++)
  272.     {
  273.       printf("%02x ", (UWORD)data[count1*16+count2]);
  274.     }
  275.  
  276.     printf("  ");
  277.     for (count2 = 0; count2 < 16; count2++)
  278.     {
  279.       if (data[count1*16+count2] >= 16)
  280.       {
  281.         printf("%c", data[count1*16+count2]);
  282.       }
  283.       else
  284.       {
  285.         printf(".");
  286.       }
  287.     }
  288.     printf("\n");
  289.   }
  290.  
  291. }}}
  292.  
  293. /***********************************************
  294.  * Die ersten DUMPBLOCKS Blöck eines Gerätes
  295.  * anzeigen
  296.  * Das handle muß gesetzt sein!
  297.  ***********************************************/
  298. void dumpblocks(void)
  299. {{{
  300. char Block[512];
  301. WORD BlockCount;
  302. LONG result;
  303.  
  304.   for (BlockCount = 0; BlockCount < DUMPBLOCKS; BlockCount++)
  305.   {
  306.     SuperOn();
  307.     result = Read((ULONG)BlockCount, 1, Block);
  308.     SuperOff();
  309. /*    printf("Block %4d\n", BlockCount);*/
  310.     if (result == 0)
  311.     {
  312. #if !READONLY
  313.       dump(Block, 512);
  314. #endif
  315.     }
  316.     else
  317.     {
  318.       printf("  Block %4d result %ld\n", BlockCount, result);
  319.     }
  320.   }
  321.  
  322. }}}
  323.  
  324.  
  325. /***********************************************
  326.  * Bus nach Geräten absuchen
  327.  ***********************************************/
  328. void scan_bus(tBusInfo Bus)
  329. {{{
  330.   tInqData  InqData;
  331.   tDevInfo  Dev;
  332.   tHandle   handle;
  333.   ULONG     MaxLen;
  334.   WORD      ret;
  335.   char      Name[20];
  336.   char      Msg[100];
  337.   UWORD     Features;
  338.  
  339. /* handle = scsicall->Open(1, 0, &MaxLen);*/
  340.  
  341.  
  342.   SuperOn();
  343.   ret = scsicall->InquireBus(cInqFirst, Bus.BusNo, &Dev);
  344.   SuperOff();
  345.  
  346.   while (ret == 0)
  347.   {
  348.     printf("  Id %2ld ", Dev.SCSIId.lo);
  349. #if TRUE
  350.     SuperOn();
  351.     ret = scsicall->CheckDev(Bus.BusNo, &Dev.SCSIId, Name, &Features);
  352.     SuperOff();
  353.     if (ret == 0)
  354.       {
  355.         printf("%s ", Name);
  356.         if (Features & cArbit)
  357.           printf(" arbit,");
  358.         if (Features & cAllCmds)
  359.           printf(" all cmds,");
  360.         if (Features & cTargCtrl)
  361.           printf(" target controlled,");
  362.         if (Features & cTarget)
  363.           printf(" target installable,");
  364.         if (Features & cCanDisconnect)
  365.           printf(" Disconnect possible,");
  366.         if (Features & cScatterGather)
  367.           printf(" scatter gather,");
  368.         printf("\b \n     ");
  369.       }
  370.     else
  371.       {
  372.  
  373.       }
  374. #endif
  375.  
  376.     memset (&InqData, 0, sizeof (tInqData));
  377.  
  378.     SuperOn();
  379.     handle = (tHandle) scsicall->Open(Bus.BusNo, &Dev.SCSIId, &MaxLen);
  380.     if ((LONG) handle >= 0)
  381.     {
  382.       SetScsiUnit(handle, 0, MaxLen);
  383.       /* erst den Header */
  384.       ret = Inquiry(&InqData, FALSE, 0, 5);
  385.       if (ret == 0L)
  386.       {
  387.         ret = Inquiry(&InqData, FALSE, 0, (WORD) MIN((WORD)5 + (WORD)InqData.AddLen, (WORD)sizeof(InqData)));
  388.       }
  389.     }
  390.  
  391.     SuperOff();
  392.  
  393.     if ((LONG) handle >= 0)
  394.     {
  395.       printf(" handle $%lx", handle);
  396.       printf(" MaxLen $%lx", MaxLen);
  397.     }
  398.  
  399.  
  400.     if (((LONG) handle >= 0) && (ret == 0L))
  401.     {
  402.       InqData.Revision[0] = 0;
  403.       printf(" %s ", InqData.Vendor);
  404.       switch (InqData.Device & 0x1F) {
  405.         case 0: printf ("direct access device");
  406.                 break;
  407.         case 1: printf ("sequential access device");
  408.                 break;
  409.         case 2: printf ("printer device");
  410.                 break;
  411.         case 3: printf ("processor device");
  412.                 break;
  413.         case 4: printf ("write-once device");
  414.                 break;
  415.         case 5: printf ("CD-ROM device");
  416.                 break;
  417.         case 6: printf ("scanner device");
  418.                 break;
  419.         case 7: printf ("optical memory device");
  420.                 break;
  421.         case 8: printf ("medium changer device");
  422.                 break;
  423.         case 9: printf ("communications device");
  424.                 break;
  425.         case 10:
  426.         case 11: printf ("ASC IT 8 (graphic arts pre-press device)");
  427.                 break;
  428.         case 0x1f: printf ("unknown device");
  429.                 break;
  430.  
  431.         default : printf(" reserved device type %h", InqData.Device);
  432.       }
  433.     }
  434.     else
  435.     {
  436.       if ((LONG) handle < 0)
  437.         printf(": no Handle -%ld", -1*(LONG)handle);
  438.       else
  439.       {
  440.         if (ret > 0)
  441.         {
  442.           printf(": Error $%x ", ret);
  443.           /* Sense-Daten ausgeben */
  444.           if (SenseMsg((REQSENSE *) &ReqBuff, Msg))
  445.           {
  446.             printf(Msg);
  447.           }
  448.         }
  449.         else
  450.         {
  451.           printf(": no Device (-$%x) ", -1*ret);
  452.         }
  453.       }
  454.     }
  455.  
  456.     printf("\n");
  457.  
  458.     if ((LONG) handle > 0)
  459.     {
  460. #if DUMPBLOCKS
  461.       /* Wenn es eines Festplatte ist, lesen wir mal den ersten Block
  462.        * und zeigen ihn an */
  463.       if ((InqData.Device & 0x1F) == 0)
  464.       {
  465.         dumpblocks();
  466.       }
  467. #endif
  468.       /* und das handle freigeben */
  469.       SuperOn();
  470.       scsicall->Close(handle);
  471.       SuperOff();
  472.     }
  473.     SuperOn();
  474.     ret = scsicall->InquireBus(cInqNext, Bus.BusNo, &Dev);
  475.     SuperOff();
  476.  
  477.     } /* while */
  478.  
  479. }}}
  480.  
  481. void search_drives(void)
  482. {{{
  483.   LONG          ret;
  484.   tBusInfo      Info;
  485.  
  486.   printf("\nsearching drives...\n");
  487.  
  488.   SuperOn();
  489.   ret = scsicall->InquireSCSI(cInqFirst, &Info);
  490.   SuperOff();
  491.   while (ret == 0)
  492.   {
  493.  
  494.     printf("\n Bus %s, No %d\n", Info.BusName, Info.BusNo);
  495.     scan_bus(Info);
  496.  
  497.     SuperOn();
  498.     ret = scsicall->InquireSCSI(cInqNext, &Info);
  499.     SuperOff();
  500.   }
  501. }}}
  502.  
  503. WORD main(void)
  504. {{{
  505.  
  506.   printf("Demo-Programm für Benutzung der SCSI-Calls");
  507.   printf("  © Steffen Engel 1995");
  508.  
  509.   if (init_scsiio() && init_scsi())
  510.     search_drives();
  511.   else
  512.     printf("SCSI-Lib nicht benutzbar");
  513.  
  514.   printf("\n Taste drücken");
  515.   do
  516.   {
  517.   } while (Cconis());
  518.   Cconin();
  519. /*
  520. */
  521.   return (0);
  522.  
  523. }}}
  524.         
  525.         
  526.         
  527.